package com.wangp.mywrite.inwork.juc._1._1_1_thread_safety;

import com.wangp.mywrite.inwork.juc.ThreadHandler;


/***
 * @author wangpeng
 * @since 2022-03-10  14:13
 *
 *<p> 如果当多个线程访问同一个可变的状态变量时没有使用合适的同步，那么程序就会出现错误。</p>
 *<p> 有三种方式可以修复这个问题：</p>
 *<p> ·不在线程之间共享该状态变量。</p>
 *<p> ·将状态变量修改为不可变的变量。</p>
 *<p> ·在访问状态变量时使用同步。</p>
 */
public class ThreadSafety {

    public static void main(String[] args) {
        unsafeMulThread();
        safeMulThread();
    }

    @SuppressWarnings(value = "all")
    private static void safeMulThread() {
        Sequence sequence = new Sequence();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                sequence.getNext();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                sequence.getNext();
            }
        });
        ThreadHandler.multiplyThreadStartThenJoin(t1, t2);
        // value = 200
        System.out.println(sequence.value);
    }

    @SuppressWarnings(value = "all")
    private static void unsafeMulThread() {
        UnsafeSequence unsafeSequence = new UnsafeSequence();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                unsafeSequence.getNext();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                unsafeSequence.getNext();
            }
        });
        ThreadHandler.multiplyThreadStartThenJoin(t1, t2);
        // value < 200
        System.out.println(unsafeSequence.value);
    }

    public static class UnsafeSequence {

        private int value;

        public int getNext() {
            return value++;
        }
    }

    public static class Sequence {

        private int value;

        public synchronized int getNext() {
            return value++;
        }
    }
}
